﻿using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using AyuBookmark.Common.Interfaces;
using AyuBookmark.Common.Models;
using Microsoft.Extensions.Logging;

namespace AyuBookmark.Service.MessageProcessing
{
    public class BookmarkMessageProcessor : IMessageProcessor
    {
        private readonly IBookmarkService _bookmarkService;
        private readonly ILogger<BookmarkMessageProcessor> _logger;

        public BookmarkMessageProcessor(
            IBookmarkService bookmarkService,
            ILogger<BookmarkMessageProcessor> logger)
        {
            _bookmarkService = bookmarkService ?? throw new ArgumentNullException(nameof(bookmarkService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public async Task<string> ProcessAsync(string message, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Processing message: {Message}", message);

                using var doc = JsonDocument.Parse(message);
                var root = doc.RootElement;

                // 获取命令类型
                if (!root.TryGetProperty("Type", out var typeProp) || typeProp.ValueKind != JsonValueKind.String)
                {
                    return CreateErrorResponse("Missing or invalid command Type");
                }

                var type = typeProp.GetString();

                // 获取数据部分
                if (!root.TryGetProperty("Data", out var dataProp) || dataProp.ValueKind != JsonValueKind.Object)
                {
                    return CreateErrorResponse("Missing or invalid command Data");
                }

                // 根据命令类型处理
                return type switch
                {
                    "AddBookmark" => await HandleAddBookmarkCommand(dataProp),
                    "GetBookmark" => await HandleGetBookmarkCommand(dataProp),
                    "DeleteBookmark" => await HandleDeleteBookmarkCommand(dataProp),
                    _ => CreateErrorResponse($"Unknown command type: {type}")
                };
            }
            catch (JsonException ex)
            {
                _logger.LogError(ex, "Failed to deserialize message");
                return CreateErrorResponse("Invalid JSON format");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing message");
                return CreateErrorResponse(ex.Message);
            }
        }

        #region 命令处理方法
        private async Task<string> HandleAddBookmarkCommand(JsonElement data)
        {
            if (!data.TryGetProperty("url", out var urlProp) || urlProp.ValueKind != JsonValueKind.String)
            {
                return CreateErrorResponse("Missing or invalid URL");
            }

            var url = urlProp.GetString();
            if (string.IsNullOrWhiteSpace(url))
            {
                return CreateErrorResponse("URL cannot be empty");
            }

            var bookmark = new Bookmark
            {
                Url = url,
                Title = data.TryGetProperty("title", out var titleProp) && titleProp.ValueKind == JsonValueKind.String
                    ? titleProp.GetString()
                    : GetTitleFromUrl(url),
                Description = data.TryGetProperty("description", out var descProp) && descProp.ValueKind == JsonValueKind.String
                    ? descProp.GetString()
                    : null,
                CreatedTime = DateTime.Now
            };

            var result = await _bookmarkService.AddBookmarkAsync(bookmark);
            return CreateSuccessResponse(new { Id = result.Id });
        }

        private async Task<string> HandleGetBookmarkCommand(JsonElement data)
        {
            if (!data.TryGetProperty("id", out var idProp) ||
                !idProp.TryGetInt32(out var id))
            {
                return CreateErrorResponse("Missing or invalid bookmark ID");
            }

            var bookmark = await _bookmarkService.GetBookmarkDetailsAsync(id);
            return bookmark != null
                ? CreateSuccessResponse(bookmark)
                : CreateErrorResponse("Bookmark not found");
        }

        private async Task<string> HandleDeleteBookmarkCommand(JsonElement data)
        {
            if (!data.TryGetProperty("id", out var idProp) ||
                !idProp.TryGetInt32(out var id))
            {
                return CreateErrorResponse("Missing or invalid bookmark ID");
            }

            var success = await _bookmarkService.DeleteBookmarkAsync(id);
            return success
                ? CreateSuccessResponse(null)
                : CreateErrorResponse("Failed to delete bookmark");
        }
        #endregion

        #region 辅助方法
        private static string CreateSuccessResponse(object data)
        {
            return JsonSerializer.Serialize(new
            {
                Success = true,
                Data = data
            });
        }

        private static string CreateErrorResponse(string message)
        {
            return JsonSerializer.Serialize(new
            {
                Success = false,
                Error = message
            });
        }

        private static string GetTitleFromUrl(string url)
        {
            try
            {
                var uri = new Uri(url);
                return uri.Host.Replace("www.", "").Replace(".com", "");
            }
            catch
            {
                return url.Length > 50 ? url[..50] + "..." : url;
            }
        }
        #endregion
    }
}